
`include "defines.v"
`define AXI_TOP_INTERFACE(name) io_memAXI_0_``name

module SimTop(
    input                               clock,
    input                               reset,

    input  [                63:0]       io_logCtrl_log_begin,
    input  [                63:0]       io_logCtrl_log_end,
    input  [                63:0]       io_logCtrl_log_level,
    input                               io_perfInfo_clean,
    input                               io_perfInfo_dump,

    output                              io_uart_out_valid,
    output [                  7:0]      io_uart_out_ch,
    output                              io_uart_in_valid,
    input  [                  7:0]      io_uart_in_ch,

    input                               `AXI_TOP_INTERFACE(aw_ready),
    output                              `AXI_TOP_INTERFACE(aw_valid),
    output [  `AXI_ADDR_WIDTH-1:0]      `AXI_TOP_INTERFACE(aw_bits_addr),
    output [                  2:0]      `AXI_TOP_INTERFACE(aw_bits_prot),
    output [    `AXI_ID_WIDTH-1:0]      `AXI_TOP_INTERFACE(aw_bits_id),
    output [  `AXI_USER_WIDTH-1:0]      `AXI_TOP_INTERFACE(aw_bits_user),
    output [                  7:0]      `AXI_TOP_INTERFACE(aw_bits_len),
    output [                  2:0]      `AXI_TOP_INTERFACE(aw_bits_size),
    output [                  1:0]      `AXI_TOP_INTERFACE(aw_bits_burst),
    output                              `AXI_TOP_INTERFACE(aw_bits_lock),
    output [                  3:0]      `AXI_TOP_INTERFACE(aw_bits_cache),
    output [                  3:0]      `AXI_TOP_INTERFACE(aw_bits_qos),
    
    input                               `AXI_TOP_INTERFACE(w_ready),
    output                              `AXI_TOP_INTERFACE(w_valid),
    output [  `AXI_DATA_WIDTH-1:0]      `AXI_TOP_INTERFACE(w_bits_data)         [3:0],
    output [`AXI_DATA_WIDTH/8-1:0]      `AXI_TOP_INTERFACE(w_bits_strb),
    output                              `AXI_TOP_INTERFACE(w_bits_last),
    
    output                              `AXI_TOP_INTERFACE(b_ready),
    input                               `AXI_TOP_INTERFACE(b_valid),
    input  [                  1:0]      `AXI_TOP_INTERFACE(b_bits_resp),
    input  [    `AXI_ID_WIDTH-1:0]      `AXI_TOP_INTERFACE(b_bits_id),
    input  [  `AXI_USER_WIDTH-1:0]      `AXI_TOP_INTERFACE(b_bits_user),

    input                               `AXI_TOP_INTERFACE(ar_ready),
    output                              `AXI_TOP_INTERFACE(ar_valid),
    output [  `AXI_ADDR_WIDTH-1:0]      `AXI_TOP_INTERFACE(ar_bits_addr),
    output [                  2:0]      `AXI_TOP_INTERFACE(ar_bits_prot),
    output [    `AXI_ID_WIDTH-1:0]      `AXI_TOP_INTERFACE(ar_bits_id),
    output [  `AXI_USER_WIDTH-1:0]      `AXI_TOP_INTERFACE(ar_bits_user),
    output [                  7:0]      `AXI_TOP_INTERFACE(ar_bits_len),
    output [                  2:0]      `AXI_TOP_INTERFACE(ar_bits_size),
    output [                  1:0]      `AXI_TOP_INTERFACE(ar_bits_burst),
    output                              `AXI_TOP_INTERFACE(ar_bits_lock),
    output [                  3:0]      `AXI_TOP_INTERFACE(ar_bits_cache),
    output [                  3:0]      `AXI_TOP_INTERFACE(ar_bits_qos),
    
    output                              `AXI_TOP_INTERFACE(r_ready),
    input                               `AXI_TOP_INTERFACE(r_valid),
    input  [                  1:0]      `AXI_TOP_INTERFACE(r_bits_resp),
    input  [  `AXI_DATA_WIDTH-1:0]      `AXI_TOP_INTERFACE(r_bits_data)         [3:0],
    input                               `AXI_TOP_INTERFACE(r_bits_last),
    input  [    `AXI_ID_WIDTH-1:0]      `AXI_TOP_INTERFACE(r_bits_id),
    input  [  `AXI_USER_WIDTH-1:0]      `AXI_TOP_INTERFACE(r_bits_user)
);

    wire                         aw_ready;
    wire                         aw_valid;
    wire [  `AXI_ADDR_WIDTH-1:0] aw_addr;
    wire [                  2:0] aw_prot;
    wire [    `AXI_ID_WIDTH-1:0] aw_id;
    wire [  `AXI_USER_WIDTH-1:0] aw_user;
    wire [                  7:0] aw_len;
    wire [                  2:0] aw_size;
    wire [                  1:0] aw_burst;
    wire                         aw_lock;
    wire [                  3:0] aw_cache;
    wire [                  3:0] aw_qos;
    wire [                  3:0] aw_region;

    wire                         w_ready;
    wire                         w_valid;
    wire [  `AXI_DATA_WIDTH-1:0] w_data;
    wire [`AXI_DATA_WIDTH/8-1:0] w_strb;
    wire                         w_last;
    wire [  `AXI_USER_WIDTH-1:0] w_user;
    
    wire                         b_ready;
    wire                         b_valid;
    wire [                  1:0] b_resp;
    wire [    `AXI_ID_WIDTH-1:0] b_id;
    wire [  `AXI_USER_WIDTH-1:0] b_user;

    wire                         ar_ready;
    wire                         ar_valid;
    wire [  `AXI_ADDR_WIDTH-1:0] ar_addr;
    wire [                  2:0] ar_prot;
    wire [    `AXI_ID_WIDTH-1:0] ar_id;
    wire [  `AXI_USER_WIDTH-1:0] ar_user;
    wire [                  7:0] ar_len;
    wire [                  2:0] ar_size;
    wire [                  1:0] ar_burst;
    wire                         ar_lock;
    wire [                  3:0] ar_cache;
    wire [                  3:0] ar_qos;
    wire [                  3:0] ar_region;
    
    wire                         r_ready;
    wire                         r_valid;
    wire [                  1:0] r_resp;
    wire [  `AXI_DATA_WIDTH-1:0] r_data;
    wire                         r_last;
    wire [    `AXI_ID_WIDTH-1:0] r_id;
    wire [  `AXI_USER_WIDTH-1:0] r_user;

   //ar
    assign ar_ready                                 = `AXI_TOP_INTERFACE(ar_ready);
    assign `AXI_TOP_INTERFACE(ar_valid)             = ar_valid;
    assign `AXI_TOP_INTERFACE(ar_bits_addr)         = ar_addr;
    assign `AXI_TOP_INTERFACE(ar_bits_prot)         = ar_prot;
    assign `AXI_TOP_INTERFACE(ar_bits_id)           = ar_id;
    assign `AXI_TOP_INTERFACE(ar_bits_user)         = ar_user;
    assign `AXI_TOP_INTERFACE(ar_bits_len)          = ar_len;
    assign `AXI_TOP_INTERFACE(ar_bits_size)         = ar_size;
    assign `AXI_TOP_INTERFACE(ar_bits_burst)        = ar_burst;
    assign `AXI_TOP_INTERFACE(ar_bits_lock)         = ar_lock;
    assign `AXI_TOP_INTERFACE(ar_bits_cache)        = ar_cache;
    assign `AXI_TOP_INTERFACE(ar_bits_qos)          = ar_qos;
  
  //r
    assign `AXI_TOP_INTERFACE(r_ready)              = r_ready;
    assign r_valid                                  = `AXI_TOP_INTERFACE(r_valid);
    assign r_resp                                   = `AXI_TOP_INTERFACE(r_bits_resp);
    assign r_data                                   = `AXI_TOP_INTERFACE(r_bits_data)[0];
    assign r_last                                   = `AXI_TOP_INTERFACE(r_bits_last);
    assign r_id                                     = `AXI_TOP_INTERFACE(r_bits_id);
    assign r_user                                   = `AXI_TOP_INTERFACE(r_bits_user);
 
  //aw
    assign aw_ready                                 = `AXI_TOP_INTERFACE(aw_ready);
    assign `AXI_TOP_INTERFACE(aw_valid)             = aw_valid;
    assign `AXI_TOP_INTERFACE(aw_bits_addr)         = aw_addr;
    assign `AXI_TOP_INTERFACE(aw_bits_prot)         = aw_prot;
    assign `AXI_TOP_INTERFACE(aw_bits_id)           = aw_id;
    assign `AXI_TOP_INTERFACE(aw_bits_user)         = aw_user;
    assign `AXI_TOP_INTERFACE(aw_bits_len)          = aw_len;
    assign `AXI_TOP_INTERFACE(aw_bits_size)         = aw_size;
    assign `AXI_TOP_INTERFACE(aw_bits_burst)        = aw_burst;
    assign `AXI_TOP_INTERFACE(aw_bits_lock)         = aw_lock;
    assign `AXI_TOP_INTERFACE(aw_bits_cache)        = aw_cache;
    assign `AXI_TOP_INTERFACE(aw_bits_qos)          = aw_qos;

  //w
    assign w_ready                                  = `AXI_TOP_INTERFACE(w_ready);
    assign `AXI_TOP_INTERFACE(w_valid)              = w_valid;
    assign `AXI_TOP_INTERFACE(w_bits_data)[0]          = w_data;
    assign `AXI_TOP_INTERFACE(w_bits_strb)          = w_strb;
    assign `AXI_TOP_INTERFACE(w_bits_last)          = w_last;
    
  //b
    assign `AXI_TOP_INTERFACE(b_ready)              = b_ready;
    assign b_valid                                  = `AXI_TOP_INTERFACE(b_valid);
    assign b_resp                                   = `AXI_TOP_INTERFACE(b_bits_resp);
    assign b_id                                     = `AXI_TOP_INTERFACE(b_bits_id);
    assign b_user                                   = `AXI_TOP_INTERFACE(b_bits_user);
    
    wire   clk;
    assign clk = clock;
    wire   resetn;
    assign resetn = ~reset;

    //inst sram-like,
    wire         inst_req     ;
    wire         inst_wr      ;
    wire  [ 1:0] inst_size    ;
    wire  [63:0] inst_addr    ; 
    wire  [63:0] inst_wdata   ;
    wire  [63:0] inst_rdata   ;
    wire         inst_addr_ok ;
    wire         inst_data_ok ;
    //data sram-like
    wire         data_req     ;    
    wire         data_wr      ;
    wire  [ 1:0] data_size    ;
    wire  [63:0] data_addr    ;
    wire  [63:0] data_wdata   ;
    wire  [63:0] data_rdata   ;
    wire         data_addr_ok ;
    wire         data_data_ok ;



cpu_axi_interface u_cpu_axi_interface(
	//ports
	.clk          		( clk          		),
	.reset       	  	( reset       		),

	.inst_req     		( inst_req     		),
	.inst_wr      		( inst_wr      		),
	.inst_size    		( inst_size    		),
	.inst_addr    		( inst_addr    		),
	.inst_wdata   		( inst_wdata   		),
	.inst_rdata   		( inst_rdata   		),
	.inst_addr_ok 		( inst_addr_ok 		),
	.inst_data_ok 		( inst_data_ok 		),
	.data_req     		( data_req     		),
	.data_wr      		( data_wr      		),
	.data_size    		( data_size    		),
	.data_addr    		( data_addr    		),
	.data_wdata   		( data_wdata   		),
	.data_rdata   		( data_rdata   		),
	.data_addr_ok 		( data_addr_ok 		),
	.data_data_ok 		( data_data_ok 		),

	.arid         		( ar_id         		),
	.araddr       		( ar_addr       		),
	.arlen        		( ar_len        		),
	.arsize       		( ar_size       		),
	.arburst      		( ar_burst      		),
	.arlock       		( ar_lock       		),
	.arcache      		( ar_cache      		),
	.arprot       		( ar_prot       		),
	.aruser       		( ar_user       		),
	.arqos        		( ar_qos        		),
	.arregion     		( ar_region     		),
	.arvalid      		( ar_valid      		),
	.arready      		( ar_ready      		),

	.rid          		( r_id          		),
	.ruser        		( r_user        		),
	.rdata        		( r_data        		),
	.rresp        		( r_resp        		),
	.rlast        		( r_last        		),
	.rvalid       		( r_valid       		),
	.rready       		( r_ready       		),

	.awid         		( aw_id         		),
	.awaddr       		( aw_addr       		),
	.awlen        		( aw_len        		),
	.awsize       		( aw_size       		),
	.awburst      		( aw_burst      		),
	.awlock       		( aw_lock       		),
	.awcache      		( aw_cache      		),
	.awprot       		( aw_prot       		),
	.awuser       		( aw_user       		),
	.awqos        		( aw_qos        		),
	.awregion     		( aw_region     		),
	.awvalid      		( aw_valid      		),
	.awready      		( aw_ready      		),

	.wuser        		( w_user        		),
	.wdata        		( w_data        		),
	.wstrb        		( w_strb        		),
	.wlast        		( w_last        		),
	.wvalid       		( w_valid       		),
	.wready       		( w_ready       		),

	.bid          		( b_id          		),
	.buser        		( b_user        		),
	.bresp        		( b_resp        		),
	.bvalid       		( b_valid       		),
	.bready       		( b_ready       		)
);



cpu u_cpu(
	//ports
	.clock             		( clock           ),
	.reset             		( reset           ),

	.inst_sram_wr      		( inst_wr      		),
	.inst_sram_req     		( inst_req     		),
	.inst_sram_addr_ok 		( inst_addr_ok 		),
	.inst_sram_data_ok 		( inst_data_ok 		),
	.inst_sram_addr    		( inst_addr    		),
	.inst_sram_wdata   		( inst_wdata   		),
	.inst_sram_rdata   		( inst_rdata   		),
	.inst_sram_size    		( inst_size    		),

	.data_sram_wr      		( data_wr      		),
	.data_sram_req     		( data_req     		),
	.data_sram_addr_ok 		( data_addr_ok 		),
	.data_sram_data_ok 		( data_data_ok 		),
	.data_sram_addr    		( data_addr    		),
	.data_sram_wdata   		( data_wdata   		),
	.data_sram_rdata   		( data_rdata   		),
	.data_sram_size    		( data_size    		),
  .io_uart_out_valid    (io_uart_out_valid),
  .io_uart_out_ch       ( io_uart_out_ch)
);



endmodule